home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / Unsupported Libraries / GXfontLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-05  |  19.2 KB  |  499 lines  |  [TEXT/MPS ]

  1. /* graphics:    
  2.     gxFont library routines
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Mike Reed, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright ©1987 - 1991 Apple Computer, Inc.  All rights reserved.
  5. */
  6.  
  7.     #include <Memory.h>
  8.     #include <Quickdraw.h>
  9.  
  10. #include "font library.h"
  11. #include "graphics libraries.h"
  12. #include "font routines.h"
  13.     #include "graphics toolbox.h"
  14.  
  15. #ifdef THINK_C
  16. #pragma options(signed_pstrs)   /* for Think C 5.0 */
  17. #endif
  18. #ifdef MacintoshIncludes
  19.     #define NewString gNewString
  20. #endif
  21.  
  22. typedef struct {
  23.     gxFont        fontID;
  24.     char*   fullName;
  25. } fontNameRecord;
  26.  
  27. static fontNameRecord commonLibraryFonts[] = {
  28.     { nil, "Chicago" },
  29.     { nil, "Courier" },
  30.     { nil, "Geneva" },
  31.     { nil, "Helvetica" },
  32.     { nil, "Monaco" },
  33.     { nil, "New York" },
  34.     { nil, "Symbol" },
  35.     { nil, "Times Roman" }
  36. };
  37.  
  38.  
  39. /***********************************
  40.  *  gxShape and gxStyle library routines to handle  fonts *
  41.  ***********************************/
  42.  
  43. gxFont GetCommonFont(commonFont fontIndex)
  44. {
  45.     if (fontIndex >= firstCommonFont && fontIndex <= lastCommonFont)
  46.     {   if (commonLibraryFonts[fontIndex].fontID == nil)
  47.             commonLibraryFonts[fontIndex].fontID = FindCNameFont(gxFullFontName, commonLibraryFonts[fontIndex].fullName);
  48.         return commonLibraryFonts[fontIndex].fontID;
  49.     }
  50.     return GXGetDefaultFont();
  51. }
  52.  
  53. void SetShapeCommonFont(gxShape s, commonFont fontIndex)
  54. {
  55.     GXSetShapeFont(s, GetCommonFont(fontIndex));
  56. }
  57.  
  58. void SetStyleCommonFont(gxStyle s, commonFont fontIndex)
  59. {
  60.     GXSetStyleFont(s, GetCommonFont(fontIndex));
  61. }
  62.  
  63. static long CLength(const char *name)
  64. {
  65.     const char *nameEnd = name;
  66.     
  67.     while ((*nameEnd++) != 0)
  68.         ;
  69.     return nameEnd - name - 1;
  70. }
  71.  
  72. gxFont FindCNameFont(gxFontName meaning, const char* name)
  73. {
  74.     gxFont fontID = nil;
  75.     GXFindFonts(0, meaning, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, CLength(name), (unsigned char *) name, 1, 1, &fontID);
  76.     return fontID;
  77. }
  78.  
  79. gxFont FindPNameFont(gxFontName meaning, const unsigned char name[])
  80. {
  81.     gxFont fontID = nil;
  82.     GXFindFonts(0, meaning, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, name[0], &name[1], 1, 1, &fontID);
  83.     return fontID;
  84. }
  85.  
  86. /************ gxFont names *************/
  87.  
  88. long FindFontCName(gxFont fontID, gxFontName meaning, char name[])
  89. {
  90.     long length = GXFindFontName(fontID, meaning, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, (unsigned char*)name, nil);
  91.  
  92.     if (name)
  93.         name[length] = 0;
  94.     return length;
  95. }
  96.  
  97. long FindFontPName(gxFont fontID, gxFontName meaning, unsigned char name[])
  98. {
  99.     long length = GXFindFontName(fontID, meaning, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
  100.  
  101.     if (name)
  102.         name[0] = length;
  103.     return length;
  104. }
  105.  
  106. long FindStyleFontCName(gxStyle s, gxFontName meaning, char name[])
  107.  {
  108.     gxFont fontID = GXGetStyleFont(s);
  109.     return(FindFontCName(fontID, meaning, name));
  110.  }
  111.  
  112. long FindStyleFontPName(gxStyle s, gxFontName meaning, unsigned char name[])
  113.  {
  114.     gxFont fontID = GXGetStyleFont(s);
  115.     return(FindFontPName(fontID, meaning, name));
  116.  }
  117.  
  118. void SetStylePNamedFont(gxStyle s, const unsigned char name[])
  119. {
  120.     gxFont fontID = FindPNameFont(gxFullFontName, name);
  121.     if (fontID != GXGetStyleFont(s))
  122.         GXSetStyleFont(s, fontID);
  123. }
  124.  
  125. void SetStyleCNamedFont(gxStyle s, const char* name)
  126. {
  127.     gxFont fontID = FindCNameFont(gxFullFontName, name);
  128.     if (fontID != GXGetStyleFont(s))
  129.         GXSetStyleFont(s, fontID);
  130. }
  131.  
  132. /************************
  133.  *  Routines for using GXFindFonts
  134.  ************************/
  135.  
  136. long CountFontFamilies(void)
  137. {
  138.     return GXFindFonts(nil, gxFamilyFontName, 0, 0, 0, 0, nil, 1, gxSelectToEnd, nil);
  139. }
  140.  
  141. gxFont FindFontFamily(long index, gxFontPlatform platform, gxFontScript script, gxFontLanguage language,
  142.     long nameLength, const unsigned char *name)
  143. {
  144.     gxFont fontID = nil;
  145.     GXFindFonts(nil, gxFamilyFontName, platform, script, language, nameLength, name, index, 1, &fontID);
  146.     return fontID;
  147. }
  148.  
  149. long CountFontStyles(gxFont family)
  150. {
  151.     return GXFindFonts(family, 0, 0, 0, 0, 0, nil, 1, gxSelectToEnd, nil);
  152. }
  153.  
  154. static gxFont GetFontStyle(gxFont family, long index)
  155. {
  156.     gxFont fontID = nil;
  157.     GXFindFonts(family, 0, 0, 0, 0, 0, nil, index, 1, &fontID);
  158.     return fontID;
  159. }
  160.  
  161. gxFont FindFontStyle(gxFont family, long index, gxFontPlatform platform, gxFontScript script, gxFontLanguage language,
  162.     long nameLength, const unsigned char *name)
  163. {
  164.     gxFont fontID = nil;
  165.  
  166.     if (index)
  167.         GXFindFonts(family, 0, 0, 0, 0, 0, nil, index, 1, &fontID);
  168.     else
  169.         GXFindFonts(family, gxStyleFontName, platform, script, language, nameLength, name, index, 1, &fontID);
  170.     return fontID;
  171. }
  172.  
  173. /****************************
  174.         Style matching routines
  175.  ****************************/
  176.  
  177. typedef struct {
  178.     Fixed       minValue;
  179.     Fixed       defaultValue;
  180.     Fixed       maxValue;
  181. } descriptorRange;
  182.  
  183. typedef struct {
  184.     descriptorRange weight;
  185.     descriptorRange width;
  186.     descriptorRange slant;
  187. } fontMatchDescriptor;
  188.  
  189. typedef struct {
  190.     Fixed       weight;
  191.     Fixed       width;
  192.     Fixed       slant;
  193. } fontStyleCoord;
  194.  
  195. /*********************************************/
  196. /*              PrepareStyleForMatching                 */
  197. /*  this sets the styles gxFont variations to that of the current gxFont    */
  198. /*  we'll use this as a master and keep it to do our matching off of    */
  199. /*  if the gxStyle already has variations then we'll check to see if  */
  200. /*  the gxFont has axes, if not we'll nuke the variations and set new */
  201. /*  ones based upon the 'fdsc' information(GXFindFontDescriptor should*/
  202. /*  look at the fond header for old type fonts      ???         */
  203. /*********************************************/
  204. static void PrepareStyleForMatching(gxStyle aStyle)
  205. {
  206.     fontStyleCoord coord;
  207.     gxFont fontID = GXGetStyleFont(aStyle);
  208.     
  209.     coord.weight = 1;
  210.     coord.width = 1;
  211.     coord.slant = 0;
  212.  
  213.     GXFindFontDescriptor(fontID, weightVariationTag, &coord.weight);  
  214.     GXFindFontDescriptor(fontID, widthVariationTag, &coord.width);    
  215.     GXFindFontDescriptor(fontID, slantVariationTag, &coord.slant);    
  216.  
  217.     /* if (!( GXGetStyleFontVariations(aStyle, nil))) */
  218.     {   gxFontVariation* variations = (gxFontVariation*)NewPtr(3 * sizeof(gxFontVariation));
  219.         {   variations[0].name = weightVariationTag;    /*will actually check to see if current variations are set*/
  220.             variations[0].value = coord.weight; /*then we'll append any needed ones*/
  221.             variations[1].name = widthVariationTag; /*need a new routine that will set and create if needed*/
  222.             variations[1].value = coord.width;
  223.             variations[2].name = slantVariationTag;
  224.             variations[2].value = coord.slant;
  225.         }
  226.         GXSetStyleFontVariations(aStyle, 3, variations);
  227.         DisposePtr((Ptr)variations);
  228.     }
  229. }
  230.  
  231. /*
  232.  *  This builds a complete description of a gxFont as it is being used in a gxStyle.
  233.  *  Use this to compare against the styles in another gxFont family, to find the closest match.
  234.  */
  235. static void BuildFontStyleCoord(gxStyle aStyle, fontStyleCoord* coord)
  236. {
  237.     gxFont fontID = GXGetStyleFont(aStyle);
  238.     long i, count;
  239.     Fixed value;
  240.     gxFontTableTag aTag;
  241.  
  242.     coord->weight = 1;
  243.     coord->width = 1;
  244.     coord->slant = 0;
  245.  
  246.     GXFindFontDescriptor(fontID, weightVariationTag, &coord->weight); 
  247.     GXFindFontDescriptor(fontID, widthVariationTag, &coord->width);   
  248.     GXFindFontDescriptor(fontID, slantVariationTag, &coord->slant);   
  249.     
  250.     count = GXGetStyleFontVariations(aStyle, nil);
  251.     if (count)
  252.     {   gxFontVariation* variations = (gxFontVariation*)NewPtr(count * sizeof(gxFontVariation));
  253.         GXGetStyleFontVariations(aStyle, variations);
  254.         for (i = 0; i < count; i++)
  255.         {   aTag = variations[i].name;
  256.             value = variations[i].value;
  257.             if (aTag == weightVariationTag)
  258.                 coord->weight = value;
  259.             else if (aTag == widthVariationTag)
  260.                 coord->width = value;
  261.             else if (aTag == slantVariationTag)
  262.                 coord->slant = value;
  263.         }
  264.         DisposePtr((Ptr)variations);
  265.     }
  266. }
  267.  
  268. /*
  269.  *  This builds a complete description of a gxFont, giving its ranges for the various styles
  270.  *      weight, width, slant.
  271.  *  If the gxFont does not support a range for a given gxStyle, then min = max = default.
  272.  */
  273. static void BuildFontMatchDescriptor(gxFont fontID, fontMatchDescriptor* descriptor)
  274. {
  275.  
  276.     descriptor->weight.minValue = descriptor->weight.defaultValue = descriptor->weight.maxValue = 0;
  277.     descriptor->width.minValue = descriptor->width.defaultValue = descriptor->width.maxValue = 0;
  278.     descriptor->slant.minValue = descriptor->slant.defaultValue = descriptor->slant.maxValue = 0;
  279.  
  280.     if (GXFindFontDescriptor(fontID, weightVariationTag, &descriptor->weight.defaultValue))
  281.         descriptor->weight.minValue = descriptor->weight.maxValue = descriptor->weight.defaultValue;
  282.     if (GXFindFontDescriptor(fontID, widthVariationTag, &descriptor->width.defaultValue))
  283.         descriptor->width.minValue = descriptor->width.maxValue = descriptor->width.defaultValue;
  284.     if (GXFindFontDescriptor(fontID, slantVariationTag, &descriptor->slant.defaultValue))
  285.         descriptor->slant.minValue = descriptor->slant.maxValue = descriptor->slant.defaultValue;
  286.  
  287.     GXFindFontVariation(fontID, weightVariationTag, &descriptor->weight.minValue, &descriptor->weight.defaultValue, &descriptor->weight.maxValue, nil);
  288.     GXFindFontVariation(fontID, widthVariationTag, &descriptor->width.minValue, &descriptor->width.defaultValue, &descriptor->width.maxValue, nil);
  289.     GXFindFontVariation(fontID, slantVariationTag, &descriptor->slant.minValue, &descriptor->slant.defaultValue, &descriptor->slant.maxValue, nil);
  290. }
  291.  
  292. /*
  293.  *  This needs to scale each difference by some amount that balances the various styles
  294.  *      weight, width, slant
  295.  *  This could be a global table, or possible gxFont defined?
  296.  */
  297. static Fixed ComputeDescriptorMetric(fontStyleCoord* coord, fontMatchDescriptor* descriptor, fontStyleCoord* setting, fontStyleCoord* remaining)
  298. {
  299.     Fixed distance = 0;
  300.     fontStyleCoord remainBuffer;
  301.  
  302.     if (remaining == nil)
  303.         remaining = &remainBuffer;
  304.  
  305.     remaining->weight = remaining->width = remaining->slant = 0;
  306.                                                                 /*setting must fall within the range of descriptor min and max*/
  307.     setting->weight = (coord->weight < descriptor->weight.maxValue) ? coord->weight: descriptor->weight.maxValue;/* min of the maximums*/
  308.     setting->weight = (setting->weight > descriptor->weight.minValue) ? setting->weight: descriptor->weight.minValue;/* max of the minimums*/
  309.     remaining->weight = coord->weight - setting->weight;    /* if positive then we need to add more bolding with a textface, if negative we need to take some away*/
  310.     distance += (remaining->weight > 0) ? FixedMultiply(remaining->weight , prefwghtweighting): -FixedMultiply(remaining->weight , prefwghtweighting);/*absolute value for distance metric */
  311.     
  312.     setting->width = (coord->width < descriptor->width.maxValue) ? coord->width: descriptor->width.maxValue;/* min of the maximums*/
  313.     setting->width = (setting->width > descriptor->width.minValue) ? setting->width: descriptor->width.minValue;/* max of the minimums*/
  314.     remaining->width = coord->width - setting->width;   /* if positive then we need to extend via textface, if negative we need to condense*/
  315.     distance += (remaining->width > 0) ? FixedMultiply(remaining->width , prefwdthweighting): -FixedMultiply(remaining->width , prefwdthweighting);/*absolute value for distance metric  */
  316.  
  317.     setting->slant = (coord->slant < descriptor->slant.maxValue) ? coord->slant: descriptor->slant.maxValue;/* min of the maximums*/
  318.     setting->slant = (setting->slant > descriptor->slant.minValue) ? setting->slant: descriptor->slant.minValue;/* max of the minimums*/
  319.     remaining->slant = coord->slant - setting->slant;   /* if positive then we need to skew clockwise via textface, if negative we need to skew counter clockwise*/
  320.     /*actually, if there is any slant at all in the coord->slant then we don't want to make an italic gxFont more italic*/
  321.     distance += (remaining->slant > 0) ? FixedMultiply(remaining->slant, prefslntweighting): -FixedMultiply(remaining->slant, prefslntweighting);/*absolute value for distance metric  this is naturally weighted to be last pref*/
  322.     /* could use something like this and then weight it??? distance += FixedDivide(remaining->slant, ff(90) ); */
  323.     if(setting->slant)
  324.         remaining->slant = 0;
  325.  
  326.     return distance;
  327. }
  328.  
  329. static void AppendVariation(gxFontVariation** variation, gxFontTableTag aTag, Fixed value)
  330. {
  331.     gxFontVariation* var;
  332.     long size = GetHandleSize((Handle)variation);
  333.     
  334.     SetHandleSize((Handle)variation, size + sizeof(gxFontVariation));
  335.     var = (gxFontVariation*)((char*)*variation + size);
  336.     var->name = aTag;
  337.     var->value = value;
  338. }
  339.  
  340. static void CreateCoordVariations(fontStyleCoord* setting, fontMatchDescriptor* descriptor, gxFontVariation* variation)
  341. {
  342.     long count = 0;
  343.  
  344.     if (setting->weight != descriptor->weight.defaultValue)
  345.     {   variation[count].name = weightVariationTag;
  346.         variation[count].value = setting->weight;
  347.         count++;
  348.     }
  349.     if (setting->width != descriptor->width.defaultValue) count++;
  350.     {   variation[count].name = widthVariationTag;
  351.         variation[count].value = setting->width;
  352.         count++;
  353.     }
  354.     if (setting->slant != descriptor->slant.defaultValue) count++;
  355.     {   variation[count].name = slantVariationTag;
  356.         variation[count].value = setting->slant;
  357.         count++;
  358.     }
  359. }
  360.  
  361. /*  currently CreateCoordTextFace makes up the difference between the variation axes and the actual settings of the old gxStyle*/
  362. static gxTextFace* CreateCoordTextFace(fontStyleCoord* remainingCoord, fontMatchDescriptor* descriptor, fontStyleCoord* setting)
  363. {
  364.     #pragma unused(setting)
  365.     
  366.     gxTextFace* newFace;
  367.     Fixed newBoldAddition = 0;
  368.     
  369.     newFace = (gxTextFace*)NewPtr(sizeof(gxTextFace) +  (1 - gxAnyNumber) * sizeof(gxFaceLayer));
  370.     newFace->faceLayers = 1;
  371.     ResetMapping(&newFace->advanceMapping);
  372.  
  373.     newFace->faceLayer[0].outlineStyle = nil;
  374.     newFace->faceLayer[0].outlineFill = gxSolidFill;
  375.     newFace->faceLayer[0].flags = 0;
  376.     /*X=default length, Y = desired percentage bold, x = setting weight, y =new percentage bold to apply*/
  377.     /*  y = XY/x    */      /*newBoldAddition = FixedDivide( FixedMultiply(remainingCoord->weight, descriptor->weight.defaultValue), setting->weight);*/
  378.      if ( (remainingCoord->weight) && (descriptor->weight.defaultValue == fixed1) ) /*if there is bold left and the gxFont is not natuarally bold*/
  379.         /*newBoldAddition = FixedDivide( FixedMultiply(remainingCoord->weight, descriptor->weight.defaultValue), setting->weight);*/
  380.         newBoldAddition = fixed1/12;  /*this is just a temporary hack until textfaces are nailed down????*/
  381.     newBoldAddition *= (remainingCoord->weight > 0) ? 1: -1;    /*increase or decrease weight*/
  382.     newFace->faceLayer[0].boldOutset.x = newBoldAddition;   /*if negative this makes lighter???*/
  383.     newFace->faceLayer[0].boldOutset.y = 0;
  384.  
  385.     if (remainingCoord->width || remainingCoord->slant)
  386.     {   gxTransform curTransform = newFace->faceLayer[0].outlineTransform = GXNewTransform();
  387.         if (remainingCoord->width)
  388.         {   Fixed newWidthFactor = fixed1+ remainingCoord->width;
  389.             GXScaleTransform(curTransform, newWidthFactor, fixed1, 0, 0);
  390.         }
  391.         if (remainingCoord->slant)
  392.             GXSkewTransform(curTransform, -fixed1/4, 0, 0, 0);/*should do a slope from angle????*/
  393.     }
  394.     else
  395.         newFace->faceLayer[0].outlineTransform = nil;
  396.     return newFace;
  397. }
  398.  
  399. static gxFont FindMatchingFont(gxStyle currentStyle, gxFont targetFamily, gxFontVariation* newVariations, gxTextFace** newFace)
  400. {
  401.     Fixed bestMetric = ff(32767);
  402.     gxFont bestFont = targetFamily;
  403.     fontStyleCoord currentCoord, bestRemaining, bestSetting;
  404.     fontMatchDescriptor bestDesc;
  405.     long styleIndex, styleCount;
  406.  
  407.     BuildFontStyleCoord(currentStyle, ¤tCoord);   /*maybe take this out later??? use preparestyleformatching*/
  408.  
  409.     styleCount = CountFontStyles(targetFamily);
  410.     for (styleIndex = 1; styleIndex <= styleCount; styleIndex++)
  411.     {   Fixed metric;
  412.         gxFont targetFont = GetFontStyle(targetFamily, styleIndex);
  413.         fontStyleCoord remainingCoord, targetSetting;
  414.         fontMatchDescriptor targetDescriptor;
  415.  
  416.         BuildFontMatchDescriptor(targetFont, &targetDescriptor);
  417.         if(!GXGetFont(targetFont, nil, nil))
  418.             DebugStr((const unsigned char *)"\pError in FindMatchingFont with targetFont");
  419.         metric = ComputeDescriptorMetric(¤tCoord, &targetDescriptor, &targetSetting, &remainingCoord);
  420.         if (metric < bestMetric)
  421.         {   bestMetric = metric;
  422.             bestFont = targetFont;
  423.             bestDesc = targetDescriptor;
  424.             bestSetting = targetSetting;
  425.             bestRemaining = remainingCoord;
  426.         }
  427.     }
  428.     if (newVariations)  /*new way we won't have to do this?????*/
  429.         CreateCoordVariations(&bestSetting, &bestDesc, newVariations);
  430.     if (newFace)
  431.         *newFace = bestMetric ? CreateCoordTextFace(&bestRemaining, &bestDesc, &bestSetting) : nil;
  432.  
  433.     return bestFont;
  434. }
  435.  
  436. static void DisposeFaceParts(gxTextFace *newFace)
  437. {
  438.     long activeLayer = newFace->faceLayers - 1;
  439.  
  440.     do {
  441.         if (newFace->faceLayer[activeLayer].outlineStyle)
  442.             GXDisposeStyle(newFace->faceLayer[activeLayer].outlineStyle);
  443.         if (newFace->faceLayer[activeLayer].outlineTransform)
  444.             GXDisposeTransform(newFace->faceLayer[activeLayer].outlineTransform);
  445.     } while (--activeLayer >= 0);
  446.     DisposePtr((Ptr) newFace);
  447. }
  448.  
  449.  
  450. void SetMatchingStyle(gxFont targetFamily, gxStyle theStyle, long matchInfo)
  451. {
  452.     gxFont toFont;
  453.     gxTextFace *newFace = nil;
  454.     gxFontVariation newVariations[3];/*will only match on wght, wdth, slnt*/
  455.     gxFont fromFont = GXGetStyleFont(theStyle);
  456.     boolean toggle = false;
  457.     
  458.     if ( !( GXGetStyleFontVariations(theStyle, nil)) )
  459.         PrepareStyleForMatching(theStyle);
  460.     if(matchInfo & useTextFaceMatching)
  461.     {
  462.         if(matchInfo & useVariationsMatching)
  463.             toFont = FindMatchingFont(theStyle, targetFamily, newVariations, &newFace);
  464.         else
  465.             toFont = FindMatchingFont(theStyle, targetFamily, nil, &newFace);
  466.     }
  467.     if(!(matchInfo & useTextFaceMatching))
  468.     {
  469.         if(matchInfo & useVariationsMatching)
  470.             toFont = FindMatchingFont(theStyle, targetFamily, newVariations, nil);
  471.         else
  472.             toFont = FindMatchingFont(theStyle, targetFamily, nil, nil);
  473.     }
  474.  
  475.     
  476.     GXSetStyleFont(theStyle, toFont);
  477.     GXSetStyleFace(theStyle, nil);    /*remove any textfaces set  will have to do this selectively in the future???*/
  478.     
  479.     if(matchInfo & useVariationsMatching)
  480.     {   short varCount = GXCountFontVariations(toFont);
  481.     
  482.         if(varCount)
  483.             GXSetStyleFontVariations(theStyle, varCount, newVariations);
  484.     }
  485.     if(matchInfo & useTextFaceMatching)
  486.     {
  487.         if(newFace)
  488.             GXSetStyleFace(theStyle, newFace);
  489.     }   
  490.     if (newFace)
  491.         DisposeFaceParts(newFace);
  492. }
  493.  
  494. gxStyle ReturnMatchingStyle(gxFont targetFamily, gxStyle theStyle, long matchInfo)
  495. {   gxStyle aStyle = GXCopyToStyle(nil, theStyle);
  496.     SetMatchingStyle(targetFamily, aStyle, matchInfo);
  497.     return(aStyle);
  498. }
  499.